/**
 * Class provides image preload functionality.
 *
 * @author Andrey Anisimov <hercules@inbox.ru>
 */

import core.util.Listeners;

class ImagePreloader {

	/**
	 * Initializes the new preloader.
	 */
	this.ImagePreloader = function() {
		this.listeners = new Listeners([
            'onImagePreloaded',
            'onPreloadFailed'
        ]);
		this.loading = false;
		this.image = new Image();
		this.image.onload = bind(this, this.onImageLoaded);
		this.image.onerror = bind(this, this.onLoadError);
	}

	/**
	 * Tries to preload an image by its URL.
	 *
	 * @param url (string) The URL of the image.
	 */
	this.preload = function(url) {
		this.url = url;
		this.loading = true;
		this.image.src = url;
	}

	/**
	 * Adds a preloader listener.
	 *
	 * @param listener (object) The listener object to add.
	 */
	this.addListener = function(listener) {
		this.listeners.add(listener);
	}

	/**
	 * Removes a preloader listener.
	 *
	 * @param listener (object) The listener object to remove.
	 */
	this.removeListener = function(listener) {
		this.listeners.remove(listener);
	}

	/**
	 * Returns whether the image is currently loading.
	 * 
	 * @return bool
	 */
	this.isLoading = function() {
		return this.loading;
	}

	this.getUrl = function() {
		return this.url;
	}

	this.getWidth = function() {
		return this.image.width;
	}

	this.getHeight = function() {
		return this.image.height;
	}

	/**
	 * @protected
	 * Fires when the image has been successfully preloaded.
	 */
	this.fireImagePreloaded = function() {
		this.listeners.call('onImagePreloaded', [ this ]);
	}

	/**
	 * @protected
	 * Fires when an error occurs during image preloading.
	 */
	this.firePreloadFailed = function() {
		this.listeners.call('onPreloadFailed', [ this ]);
	}

	this.onImageLoaded = function() {
		this.loading = false;
		this.fireImagePreloaded();
	}

	this.onLoadError = function() {
		this.loading = false;
		this.firePreloadFailed();
	}
}